#include "ifs.h"
#include <string.h>
#include <linked_list.h>
#include "kmm.h"
#include "process.h"
#include "errno.h"

LLIST *		ifs_table;
uint32_t	ifs_count;

void ifs_initialize(){
	ifs_table = (LLIST *) kmalloc(sizeof(LLIST));
	llist_create(ifs_table);
	ifs_count = 0;
}

void ifs_register(ifs_descriptor_t *desc){
	LLIST *ifs_entry = (LLIST *) kmalloc(sizeof(LLIST));
	ifs_entry->value = (void *) desc;
	llist_add_end(ifs_table,ifs_entry);
	ifs_count++;
}

ifs_descriptor_t *ifs_get_desc(char *type){
	for (uint32_t current = 0;current < ifs_count;current++){
		LLIST *ll_f = kllist_get(ifs_table,current);
		if (ll_f == 0)
			return 0;
		ifs_descriptor_t *ifs_d = (ifs_descriptor_t *) ll_f->value;
		if (strcmp(ifs_d->ifs_name,type) == 0)
			return ifs_d;
	}
	return 0;
}

int ifs_mount(struct vfs_node* mp,struct vfs_node* dev,char *type){
	struct vfs_node * ifs_root;
	ifs_descriptor_t *desc = ifs_get_desc(type);
	if (((mp->flags & VFS_DIRECTORY_FLAG) == 0) || desc == 0){
		get_current_process()->errno = EACCES;
		return 0;
	}
	ifs_root = desc->ifs_mount_cb(dev);
	if (ifs_root == 0){
		get_current_process()->errno = ENXIO;
		return 0;
	}
	mp->ptr = ifs_root;
	mp->flags |= VFS_MOUNTPOINT_FLAG;
	return 1;
}

int ifs_umount(struct vfs_node * mp,char *type){
	ifs_descriptor_t *desc = ifs_get_desc(type);
	if (((mp->flags & VFS_MOUNTPOINT_FLAG) == 0) || desc == 0){
		get_current_process()->errno = EACCES;
		return 0;
	}
	desc->ifs_umount_cb(mp->ptr);
	mp->ptr = 0;
	mp->flags &= ~VFS_MOUNTPOINT_FLAG;
	return 1;
}